/**
 * 
 */
package orderProcessingProcess.client.junit;


import static org.junit.Assert.fail;

import orderProcessingProcess.exceptions.faults.UnknownCustomerFault;
import orderProcessingProcess.exceptions.faults.CustomerNotAddedFault;
import orderProcessingProcess.exceptions.faults.CustomerNotUpdatedFault;
import orderProcessingProcess.model.Address;
import orderProcessingProcess.model.Payment_Preference;
import orderProcessingProcess.model.Customer;
import orderProcessingProcess.server.CustomerManagementServiceSOAP;

import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;


/**
 * @author tom
 *
 */
public final class TestCustomerManagementServiceSOAP {

	private static CustomerManagementServiceSOAP client;
    
	@BeforeClass
	public static void init()
	{
		JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
		factory.getInInterceptors().add(new LoggingInInterceptor());
		factory.getOutInterceptors().add(new LoggingOutInterceptor());
		factory.setServiceClass(CustomerManagementServiceSOAP.class);
		factory.setAddress("http://localhost:8086/customersoap");
		client = (CustomerManagementServiceSOAP) factory.create();
	}

	@Test
	public void testGetCustomer() {
		
		// Test get customer 00001
		try { 
			Customer c = client.getCustomer("00001");
			Assert.assertNotNull(c);
			Assert.assertEquals( "00001", c.getId() );
		} catch (UnknownCustomerFault e) {
			fail("Raised UnkownCustomerFault for existing customer");
		}

		// Test get non-existent customer
		try {
			//Customer c = 
			client.getCustomer("xyz");
			// must throw an exception
			fail("Should have raised UnkownCustomerFault");
		} catch (UnknownCustomerFault e) {
			Assert.assertTrue(true);
		}
	}
	
	@Test
	public void testAddCustomer() {
		Address a9 = new Address();
		a9.setId("009");
		a9.setStreet("9th Street");
		a9.setCity("San Francisco");
		a9.setHouse(9);
		a9.setDoor(9);
		a9.setZip_code("90000");

		Customer c9 = new Customer();
		c9.setId("00009");
		c9.setName("Joe Niner");
		c9.setAddress(a9);
		c9.setPaymentPreference(Payment_Preference.Credit_Card);

		try {
			// try to add Customer
			client.addCustomer(c9);
		} catch (CustomerNotAddedFault e) {
			fail("Raised CustomerNodAddedFault when adding customer");
		}

		// check that customer was added
		try {
			c9 = client.getCustomer("00009");
			Assert.assertNotNull(c9);
			Assert.assertEquals( "00009", c9.getId());
		} catch (UnknownCustomerFault e) {
			fail("Raised UnkownCustomerFault when getting added customer");
		}
		
		// delete added customer
		try {
			client.deleteCustomer("00009");
		} catch (UnknownCustomerFault e) {
			fail("Raised UnknownCustomerFault when deleteing added customer");
		}
	}
	
	@Test
	public void testUpdateCustomer() {
		Customer c_old = null;
		// get customer 00004	

		try {
			c_old = client.getCustomer("00004");
		} catch (UnknownCustomerFault e) {
			fail("Raised UnkownCustomerFault when getting existing customer");
		}
		
		// change name and payment Preference
		Customer c_new = c_old;
		c_new.setName("Mary Bar-None");
		c_new.setPaymentPreference(Payment_Preference.Bank_Transfer);
		
		// update customer
		try {
			client.updateCustomer("00004", c_new );
		} catch (UnknownCustomerFault e) {
			fail("Raised UnkownCustomerFault when getting existing customer");
		} catch (CustomerNotUpdatedFault e) {
			fail("Raised CustomerUpdatedFault when getting existing customer");
		}

		
		// get customer data and verify changes
		try {
			c_new = client.getCustomer("00004");
			Assert.assertNotNull(c_new);
			Assert.assertEquals( "00004", c_new.getId());
			Assert.assertEquals( "Mary Bar-None", c_new.getName() );
			Assert.assertTrue( c_new.getPaymentPreference() == Payment_Preference.Bank_Transfer );
		} catch (UnknownCustomerFault e) {
			fail("Raised UnkownCustomerFault when getting updated customer");
		}

		// try to update with conflicting path and id in customer
		try {
			client.updateCustomer("00005", c_new );
			// must throw a CustomerNotUpdated exception
			fail("Shuould have raised CustomerNotUpdatedFault when updating with conflicting ids");
		} catch (CustomerNotUpdatedFault e) {
			Assert.assertTrue( true );
		} catch (UnknownCustomerFault e) {
			// wrong exception
			fail("Raised UnkownCustomerFault, not CustomerNotUpdatedFault when updating with conflicting ids");
		}

		// try to update customer that does not exist
		c_new.setId("abc");
		try {
			client.updateCustomer("abc", c_new );
			// must throw a UnkownCustomer exception
			fail("Shuould have raised UnkownCustomerFault when updating nonexisting customer");
		} catch (UnknownCustomerFault e) {
			Assert.assertTrue(true);
		} catch (CustomerNotUpdatedFault e) {
			// wrong exception
			fail("Raised CustomerNotUpdatedFault, not UnkownCustomerFault when updating nonexisting customer");
		}

		// restore old customer data
		try {
			client.updateCustomer("00004", c_old );
		} catch (UnknownCustomerFault e) {
			fail("Raised UnkownCustomerFault when restoring customer data");
		} catch (CustomerNotUpdatedFault e) {
			fail("Raised CustomerNotUpdatedFault when restoring customer data");
		}
	}
	
	@Test
	public void testDeleteCustomer() {

		Customer c3 = null;
		// remember this customer so that we can restore him after the test
		try {
			c3 = client.getCustomer("00003");
		} catch (UnknownCustomerFault e) {
			fail("Raised UnkownCustomerFault when getting existing customer");
		}

		// delete customer 00003
		try {
			client.deleteCustomer("00003");
		} catch (UnknownCustomerFault e) {
			fail("Raised UnkownCustomerFault when getting deleting existing customer");
		}
        
		// check that customer 00003 cannot be found 
		try {
			Assert.assertNull( client.getCustomer("00003") );
			fail("Should have raised UnkownCustomerFault when getting deleted customer");
		} catch (UnknownCustomerFault e) {
			Assert.assertTrue( true );
		}

        
		// try do delete non-existent customer
		try {
			client.deleteCustomer("xyz");
			fail("Should have raised UnkownCustomerFault when deleting nonexisting customer");
		} catch (UnknownCustomerFault e) {
			Assert.assertTrue( true );
		}

		// restore the customer
		try {
			client.addCustomer(c3);
		} catch (CustomerNotAddedFault e) {
			fail("Raised CustomerNotAddedFault when restoring deleted customer");
		}

	}


}
